package control_monitor;

public class Monitor
{
	//Atributos
    	private int [] estado_actual;
    	private int [][] matriz_incidencia;
    	private boolean estado_valido;
    	
    //Exclusion mutua entrada

    	SemaforoBinario mutex=new SemaforoBinario(1);
    	
    //Cola antiguos.
    	CVSemaforo colaantiguos= new CVSemaforo(mutex);  
       
    //Constructor
    public Monitor(int[][] matriz, int[] marcado_inicial) 
    {
        this.matriz_incidencia = matriz;
        this.estado_actual = marcado_inicial;
    }

    //Ejecutar la RED DE PETRI
    public void ejecutar_transicion(int disparo)
    {
        //Solicitar la exclusion mutua del monitor al semaforo de la cola de entrada
    	mutex.Wait();
    	estado_valido=false;
    	
    	int[] disparos;
    	disparos = new int[matriz_incidencia.length];
    	
    	for(int i=0; i<matriz_incidencia.length; i++)
    	{
    		disparos[i]=0;    		
    	}
    	
    	disparos[disparo-1]=1;
    	
    	int [] vector_aux;
    	int [] pruebaestado = null;	
    	
    	while(!estado_valido)
    	{
    		boolean negativo=false;
    	//EJECUTAR ECUACION
    		vector_aux = producto_matriz_vector(matriz_incidencia, disparos);	
    		pruebaestado = suma_vectores(estado_actual, vector_aux);
		
    	//Comprobar el este vector de estado de prueba, buscando alguna posicion negativa.
    		for (int k=0;k<pruebaestado.length;k++)
    		{
    			if (pruebaestado[k]<0)
    			{
    				negativo = true;
    				//break;
    			}
    		}
    		
    		if(negativo==false)
    		{
    			estado_valido=true;
    		}
    		else
    		{
    			/*
    			System.err.print("Estado actual: ");
				for (int k=0;k<estado_actual.length;k++)
	    		{
					System.err.print(estado_actual[k] + " ");    					
	    		}  	
				System.err.println("");
				*/
				
    			colaantiguos.Delay();    			    			
    		}

    	}
    		
    		if(estado_valido==true)
    		{   //Actualizar el estado
    				estado_actual = pruebaestado;
    				estado_valido=false;
    				
    				/*
    				System.err.print("Estado actual: ");
    				for (int k=0;k<estado_actual.length;k++)
    	    		{
    					System.err.print(estado_actual[k] + " ");    					
    	    		}  	
    				System.err.println("");
    				*/
    				
    				//Despertar a alguien y devolver el permiso para ejecutar
					//Consultar cola de viejos
    					colaantiguos.Resume();
    					mutex.Signal();
    					return;    		 		
    		}		
    				
    		System.err.println("ERRRRROERRRRRORRRERRRRRORRRERRRRRORRRERRRRRORRRERRRRRORRRERRRRRORRRRRR LLEGO EN MONITOR MALLL!!");
			return;
		
    }//Fin del metodo ejecutar_transicion
	
   
	//Sumar dos vectores
    private int[] suma_vectores(int A[], int B[])
    {
        int [] resultado = new int [A.length];
	
        if ((A.length == B.length))
        {
            for (int i = 0; i<A.length; i++)
            {	resultado [i] = A[i] + B[i];	}
            return resultado;
        }
        else
        {	return null;	}
    }//Fin del metodo sumar dos vectores
    
    //Multiplicar una matriz por un vector
    private int [] producto_matriz_vector(int matriz[][], int vector[])
    {
        int resultado[] = new int [matriz.length]; 
        int suma = 0;
	 
	//	if ((matriz[0].length == vector.length))
		//{
            for(int i = 0; i <matriz.length; i++)
            {
                suma = 0;
                for (int j = 0; j < matriz[0].length; j++ )
                {	 suma = suma + matriz[i][j] * vector[j];	}
                resultado[i] = suma;
            }
            
            /*
            System.err.println("Resultadoooo IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII");
            
            for(int i=0; i<matriz.length; i++)
            {
            	
            System.err.println(resultado[i]);
            } 
            */
            return resultado;
		//}
		//else
		//{   return null;    }
    }//Fin del metodo multiplicar matriz por vector
	    
}//Fin de la clase monitor